# 引用其他目录
import sys
sys.path.append("..")

class CanSignal:

    name = '(no name)'
    fullname = '(name_id)'
    frame_id = 0
    start_pos = 0
    bit_length = 0
    # TODO:
    scale = 1.0
    offset = 0.0
    unit = 'TODO'
    comment = 'TODO'

    def __init__(self, frame_id, info):
        self.name = info[1]
        self.fullname = self.name
        self.frame_id = frame_id
        pos = info[3].split("@")
        pos = pos[0].split("|")
        self.start_pos = int(pos[0])
        self.bit_length = int(pos[1])

    def dict(self):
        item = {
            'name': self.name,
            'fullname': self.fullname,
            'frame_id': self.frame_id,
            'start_pos': self.start_pos,
            'bit_length': self.bit_length,
        }
        return item

    def make_fullname(self):
        self.fullname = self.name + '_' + str(self.frame_id)

class CanFrame:

    id = 0
    name = '(no name)'
    length = 0
    node = '(no node)'

    def __init__(self, info):
        self.id = int(info[1])
        self.name = info[2][:-1]
        self.length = int(info[3])
        self.node = info[4]

    def dict(self):
        item = {
            'id': self.id,
            'name': self.name,
            'length': self.length,
            'node': self.node,
        }
        return item

class DbcFile:

    outfile = None

    curr_frame = None
    frame_list = []
    signal_list = []

    frame_dict = {}
    signal_dict = {}

    def __init__(self):
        pass

    def parse_signal(self, info):
        signal = CanSignal(self.curr_frame.id, info)
        self.signal_list.append(signal)
        print("[SIGNAL] %s" % signal.dict(), file=self.outfile)

    def parse_frame(self, info):
        frame = CanFrame(info)
        self.frame_list.append(frame)
        print("[FRAME] %s" % frame.dict(), file=self.outfile)
        self.curr_frame = frame

    def parse_frames_signals(self, file):
        line = file.readline()
        while line!='':
            info = line.split()
            if len(info) > 0:
                if info[0]=='BO_':
                    self.parse_frame(info)
                elif info[0]=='SG_':
                    self.parse_signal(info)
                else:
                    pass
                    # print("[IGNORE]%s" % line[:-1])
            line = file.readline()

    def check_same_names(self):
        for a in self.signal_list:
            for b in self.signal_list:
                if a!=b:
                    if a.fullname == b.fullname:
                        a.make_fullname()
                        b.make_fullname()

    def make_frame_dict(self):
        count = 0
        for frame in self.frame_list:
            item = frame.dict()
            name = item['name']
            self.frame_dict[name] = item
            print("%d: %s" % (count, item), file=self.outfile)
            count += 1

    def make_signal_dict(self):
        count = 0
        for signal in self.signal_list:
            item = signal.dict()
            name = item['fullname']
            self.signal_dict[name] = item
            print("%d: %s" % (count, item), file=self.outfile)
            count += 1

    def load_file(self, path):
        self.outfile = open(path+".txt", 'w')
        print("load file: %s" % path, file=self.outfile)
        file = open(path, 'r')

        # parse frames and signals
        self.parse_frames_signals(file)

        # check signal same name
        # use full name to identify different signal with same name
        self.check_same_names()

        self.make_frame_dict()
        self.make_signal_dict()

        file.close()
        self.outfile.close()

if __name__ == '__main__':

    dbc_path = "../examples/example1.dbc"
    dbc_file = DbcFile()
    dbc_file.load_file(dbc_path)
